package main

import (
	"bufio"
	"fmt"
	"html/template"
	"os"
)

const Version = "v1.0.0"

type Message struct {
	Title       string
	MessageList []string
}

type Write struct {
	Message
	out      *bufio.Writer
	outFile  *os.File
	template string
	num      int
}

func (w *Write) Close() {
	err := w.outFile.Close()
	if err != nil {
		return
	}
}
func (w *Write) WriteToHtml() {
	check := func(err error) {
		if err != nil {
			fmt.Println(err)
			return
		}
	}
	t, err := template.New("test").Parse(temple)
	check(err)
	err = t.Execute(w.out, w.Message)
	if err != nil {
		fmt.Println(err)
		return
	}
}

func (w *Write) WriteToTxt() {
	for i := range w.MessageList {
		_, err := w.out.WriteString(w.MessageList[i])
		if err != nil {
			fmt.Println("文件写入失败", err)
			return
		}
		//_, err := w.outFile.WriteString(w.Message.MessageList[i])
		err = w.out.Flush() // 一定要使用flush, 否则很可能不能成功写入硬盘
		if err != nil {
			fmt.Println("文件保存失败", err)
		}
		//fmt.Println("写入字节数:", num)
		defer w.Close()
	}
}

func (w *Write) BuildMessage(results []Checked) {
	w.Message = Message{Title: "Logical-Check"}
	msg := fmt.Sprintf("Logical-Check,Version:%s\n", Version)
	w.MessageList = append(w.MessageList, msg)
	for i := range results {
		actionChecks := results[i].actions
		for j := range actionChecks {
			caseExprChecks := actionChecks[j].exprCheck
			w.buildMessageChild(caseExprChecks)
		}
		if results[i].Err != nil {
			for j := range results[i].Err {
				w.num++
				msg := fmt.Sprintf("\n[%d]\n", w.num)
				w.MessageList = append(w.MessageList, msg, results[i].Err[j])
			}
		}
	}
	//fmt.Println(w.MessageList)
}

func (w *Write) buildMessageChild(exprChecks []*ExprCheck) {
	var msg string
	for i := range exprChecks {

		exprCheck := exprChecks[i]
		if exprCheck.Type == CaseCheckType {
			w.num++
			msg = fmt.Sprintf("\n[%d]\n", w.num)
			msg += fmt.Sprintf("[%s:%d]\n\t设备编号:%s\n\t设备动作:%s\n\t%s\t[%v]\n",
				exprCheck.filePath, exprCheck.line, exprCheck.device, exprCheck.action, exprCheck.message, exprCheck.expr.str)
			//fmt.Println(msg)
			w.MessageList = append(w.MessageList, msg)

		} else if exprCheck.Type == LogicalCheckType {

			if exprCheck.childCheck != nil {
				msg = fmt.Sprintf("\t%s:\n", exprCheck.message)
				if exprCheck.expr != nil {
					msg += fmt.Sprintf("\t\t[源 ]\t[%s:%6d]\t%v\n", exprCheck.filePath, exprCheck.line, exprCheck.expr.FullStr)
				}
				if exprCheck.childCheck[0].target != nil {
					msg += fmt.Sprintf("\t\t[目标]\t[%s:%6d]\t%v\n",
						exprCheck.childCheck[0].target.filePath, exprCheck.childCheck[0].target.line, exprCheck.childCheck[0].target.FullStr)
				}

			} else {
				msg = fmt.Sprintf("\t\t%s\t[%v]\n", exprCheck.message, exprCheck.expr.str)
			}
			//fmt.Println(msg)
			w.MessageList = append(w.MessageList, msg)
		} else if exprCheck.Type == MissExpression || exprCheck.Type == MoreExpression {
			msg = fmt.Sprintf("\t\t[源]\t%s\t%v\n", exprCheck.message, exprCheck.expr.expr)
			//fmt.Println(msg)
			w.MessageList = append(w.MessageList, msg)
		} else if exprCheck.Type == ErrorCheckType {
			//fmt.Println(exprCheck.message)
			//w.MessageList = append(w.MessageList, exprCheck.message)
		}

		if exprCheck.childCheck != nil {
			w.buildMessageChild(exprCheck.childCheck)
		}
	}

}

func NewDefaultWrite(filePath string) *Write {
	f, ok := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm)
	if ok != nil && os.IsNotExist(ok) {
		fmt.Println(ok.Error())
		return nil
	}
	return &Write{
		out:     bufio.NewWriter(f),
		outFile: f,
	}
}
